#ifndef _classe_h
     #define _classe_h

#include <Db.hpp>   //Pour TFieldType
#include "uEtat.h"
/*typedef enum {
    NO_TYPE = -1,

    TYPE_NUMERIQUE,
    TYPE_CHAINE,

    NB_TYPE
} TYPE_VAR;*/

typedef enum  {
     TC_NOTYPE=-2,
     TC_LETTRE,
     TC_BLANC,
     TC_CHIFFRE,
     TC_OPERATEUR,
     TC_PROG,
     TC_GUIL
}TYPE_CAR;

/*class TVar : public TObject{

    private:
        TFieldType Type;
    public:
        __fastcall TVar( ){};
        virtual TVar  __fastcall operator  +(const TVar &c)const = 0;
};*/

/*typedef struct {
    TFieldType Type;
    AnsiString ValeurC;
} Var;*/

class cHelp
{
public:
  char *Nom,*Prototype;
};

class TCalculDeFormules;
class TVar;
typedef void __fastcall (__closure *TErrorEvent)(const AnsiString &Message);
typedef bool __fastcall (__closure *TVariableEvent)(const AnsiString &Variable, TFieldType &Type, AnsiString &Valeur);

typedef enum { EL_Simple = false, EL_Complex = true} TYPE_EL;


//typedef bool __fastcall (__closure *VAR_FUNC)( bool bAFaire);
class TVar : public TObject
{
    __published :
        AnsiString __fastcall operator=( bool bAFaire);
        AnsiString __fastcall operator==( bool bAFaire);
        AnsiString __fastcall operator!=( bool bAFaire);
        virtual AnsiString __fastcall IsNull( bool bAFaire);

    protected :
        TCalculDeFormules *m_Calc;
        TFieldType m_Type;
        AnsiString m_Valeur;
        AnsiString m_Variable;
        virtual void __fastcall SetValeur( const AnsiString &s) { m_Valeur = s;};
        void __fastcall Lit2Params( AnsiString &a, AnsiString &b, bool bAFaire);
    private :
        static const cHelp TabHelp[];
    public :
        __fastcall TVar(TCalculDeFormules *Calc, const AnsiString &Variable):TObject()
            {m_Calc = Calc; m_Variable = Variable;};
        __fastcall TVar(TVar *v, const AnsiString &Variable):TObject()
            {if( v){ m_Valeur = v->Valeur; m_Calc = v->m_Calc;} m_Variable = Variable;};

        __property TFieldType  Type={read=m_Type};
        __property AnsiString Valeur={read=m_Valeur,write=SetValeur};
        void __fastcall Help( TTreeNode *t);
};
class TVarNum : public TVar
{
    __published :
        AnsiString __fastcall operator>=( bool bAFaire);
        AnsiString __fastcall operator<=( bool bAFaire);
        AnsiString __fastcall operator>( bool bAFaire);
        AnsiString __fastcall operator<( bool bAFaire);
        AnsiString __fastcall operator&&( bool bAFaire);
        AnsiString __fastcall operator||( bool bAFaire);

        AnsiString __fastcall operator+=( bool bAFaire);
        AnsiString __fastcall operator+( bool bAFaire);
        AnsiString __fastcall operator-( bool bAFaire);
        AnsiString __fastcall operator*( bool bAFaire);
        AnsiString __fastcall operator/( bool bAFaire);
        AnsiString __fastcall abs( bool bAFaire);
        AnsiString __fastcall length( bool bAFaire);
        AnsiString __fastcall div( bool bAFaire);
        AnsiString __fastcall round( bool bAFaire);
        AnsiString __fastcall mod( bool bAFaire);
        AnsiString __fastcall pos( bool bAFaire);
        AnsiString __fastcall min( bool bAFaire);
        AnsiString __fastcall max( bool bAFaire);
        AnsiString __fastcall StringToNum( bool bAFaire);
        AnsiString __fastcall Sqrt( bool bAFaire);
        AnsiString __fastcall pow( bool bAFaire);
        AnsiString __fastcall pourcent( bool bAFaire);
        AnsiString __fastcall DecodeDate( bool bAFaire);
        AnsiString __fastcall DecodeTime( bool bAFaire);
        AnsiString __fastcall CurrentDay( bool bAFaire);
        AnsiString __fastcall CurrentMonth( bool bAFaire);
        AnsiString __fastcall CurrentYear( bool bAFaire);
        AnsiString __fastcall CurrentHour( bool bAFaire);
        AnsiString __fastcall CurrentMin( bool bAFaire);
        AnsiString __fastcall CurrentSec( bool bAFaire);
        virtual AnsiString __fastcall IsNull( bool bAFaire);
    private :
        void __fastcall SetValeur( const AnsiString &s);
        static double __fastcall ToDoubleDNS( const AnsiString &s);
        static bool   __fastcall IsDNS( const AnsiString &s);
        static const cHelp TabHelp[];
    public :
        __fastcall TVarNum(TCalculDeFormules *Calc, const AnsiString &Variable):TVar( Calc, Variable){m_Type = ftFloat; m_Valeur ="0";};
        __fastcall TVarNum(TVarNum *v, const AnsiString &Variable):TVar( v, Variable){m_Type = ftFloat; if( m_Valeur.IsEmpty()) m_Valeur ="0";};
    void __fastcall Help( TTreeNode *t);
};
class TVarChaine : public TVar
{
    __published :
        AnsiString __fastcall operator>=( bool bAFaire);
        AnsiString __fastcall operator<=( bool bAFaire);
        AnsiString __fastcall operator>( bool bAFaire);
        AnsiString __fastcall operator<( bool bAFaire);
        AnsiString __fastcall operator+( bool bAFaire);
        AnsiString __fastcall operator+=( bool bAFaire);
        AnsiString __fastcall LowerCase( bool bAFaire);
        AnsiString __fastcall UpperCase( bool bAFaire);
        AnsiString __fastcall NumToString( bool bAFaire);
        AnsiString __fastcall CurrentDateToStr( bool bAFaire);
        AnsiString __fastcall CurrentTimeToStr( bool bAFaire);
        AnsiString __fastcall CurrentDateTimeToStr( bool bAFaire);
        AnsiString __fastcall SubString( bool bAFaire);
        AnsiString __fastcall Trim( bool bAFaire);
    private :
        static const cHelp TabHelp[];
    public :
        __fastcall TVarChaine( TCalculDeFormules *Calc, const AnsiString &Variable):TVar( Calc, Variable){m_Type = ftString;};
        __fastcall TVarChaine( TVarChaine *v, const AnsiString &Variable):TVar( v, Variable){m_Type = ftString;};
        void __fastcall Help( TTreeNode *t);
};

class TCalculDeFormules: public TComponent//TObject
{
        friend class TVar; friend class TVarNum; friend class TVarChaine;
    private:
        bool           m_bCalcEncours;
        AnsiString     m_Formule;
        int            m_nIndice;
        int            m_nLigne;

        AnsiString     m_Resultat;
        int            m_nValRetour;
        bool           m_bPremierReturn;
        TStringList   *m_LstVar;
        char          *m_ChaineT;
        bool           m_bReturn;
        AnsiString     m_SousChaine;
        TErrorEvent    m_OnError;
        TVariableEvent m_OnVariableEvent;

        void  __fastcall Message( const AnsiString &aMessage );

        void  __fastcall throwIfFalse( bool b, const AnsiString &s=EmptyStr);
        void  __fastcall Erreur( const AnsiString &aMessage );
        void  __fastcall Avertissement( const AnsiString &aMessage );

        static bool  __fastcall bIsLettre( char Car );
        static bool  __fastcall bIsChiffre( char Car );
        static bool  __fastcall bIsBlanc( char Car );
        static bool  __fastcall bIsProg( char Car );
        static bool  __fastcall bIsOperateur( char Car );
        static bool  __fastcall bIsSautLigne( char Car );
        static bool  __fastcall bIsGuillemet( char Car );
        static bool  __fastcall bIsCaractere (char Car );

        static bool  __fastcall IsString( const AnsiString &s);
        static bool  __fastcall IsNomVar( const AnsiString &s);
        static bool  __fastcall IsNombre( const AnsiString &s);
        static bool  __fastcall IsNomOperateur( const AnsiString &s);

        void      __fastcall PasseBlancs();
        static TYPE_CAR  __fastcall nTypeCar( char Car );
        bool      __fastcall DonneMotSuivant( AnsiString &aMot );
        bool      __fastcall LitMotSuivant( const AnsiString &aChaine );

        bool      __fastcall LitNomVariable( AnsiString &s );
        TVar*     __fastcall GetVariable( const AnsiString &aChaine);

        bool      __fastcall LireJusqu_a( AnsiString &aVariable, char c);
        bool      __fastcall LireCondition( bool &bValeur, bool bAFaire);
        bool      __fastcall LireElement( AnsiString &aRetour, TFieldType &Type, bool bAFaire,
                                          TVar *pvEntree, TYPE_EL bComplexe);
        bool      __fastcall LireGroupeElement( AnsiString &aRetour, bool bAFaire, TVar *pv = NULL, TYPE_EL bComplexe = EL_Complex);
        bool      __fastcall LireInstruction( bool bAFaire );
        bool      __fastcall LireGroupeInstructions( bool bAFaire, bool bSimple);
        bool      __fastcall VariableChaine( AnsiString &aChaine );
        void      __fastcall Init( );
        void      __fastcall SetFormule( const AnsiString &Formule);
        static const cHelp TabHelp[];
    __published:
        bool __fastcall _return( bool bAFaire);
        bool __fastcall _if( bool bAFaire);
        bool __fastcall _for( bool bAFaire);
        bool __fastcall _do( bool bAFaire);
        bool __fastcall _while( bool bAFaire);
        bool __fastcall _num( bool bAFaire);
        bool __fastcall _string( bool bAFaire);

    public:
        __fastcall TCalculDeFormules( const AnsiString &Formule=EmptyStr);
        virtual __fastcall ~TCalculDeFormules();

        bool  __fastcall Execute( AnsiString &Resultat);
        void  __fastcall FonctionsDispo( TTreeNodes *li);
        void  __fastcall AddHelp( TTreeNode *t, const AnsiString &MotCle, const char* pComment);
        void  __fastcall Help( TTreeNode *t);

        __property TErrorEvent    OnError={read=m_OnError, write=m_OnError};
        __property TVariableEvent OnVariable={read=m_OnVariableEvent, write=m_OnVariableEvent};

        __property bool       bCalcEncours={read=m_bCalcEncours};
        __property AnsiString Formule={/*read=m_Formule,*/ write=SetFormule};
//        __property AnsiString Resultat={read=m_Resultat/*, write=m_Resultat*/};
        void __fastcall Help( TTreeNode *t,const cHelp *Tableau,int Taille);
};
#define LireGroupeInstructionsSimple( bAFaire) LireGroupeInstructions( bAFaire, true)
#define LireGroupeInstructionsComplexe( bAFaire) LireGroupeInstructions( bAFaire, false)

#define LireElementSimple( bAFaire)   LireGroupeInstructions( bAFaire, true)
#define LireElementComplexe( bAFaire) LireGroupeInstructions( bAFaire, false)

void ETATAPI GetMotsCles( TTreeNodes *li);
#endif
